package org.javahispano.javacup.modelo;

/**Configuracion de parametros*/
public class Constantes {

	//##################################//
	//###### Dimensiones [metros] ######//
	//##################################//
	/**Largo del campo donde se realiza el juego*/
	public static final double LARGO_CAMPO_JUEGO = 105;
	/**Ancho del campo donde se realiza el juego*/
	public static final double ANCHO_CAMPO_JUEGO = 68;
	/**Largo total campo (cesped)*/
	public static final double LARGO_CAMPO = 113;
	/**Ancho total campo (cesped)*/
	public static final double ANCHO_CAMPO = 73;
	/**Largo del arco*/
	public static final double LARGO_ARCO = 7.32;
	/**Altura del arco*/
	public static final double ALTO_ARCO = 3;
	/**Largo del area grande*/
	public static final double LARGO_AREA_GRANDE = LARGO_ARCO + 16.5 * 2;
	/**Ancho del area grande*/
	public static final double ANCHO_AREA_GRANDE = 16.5;
	/**Distancia desde el punto penal al arco*/
	public static final double DISTANCIA_PENAL = 11;
	/**Radio del circulo penal que sale fuera del area grande*/
	public static final double RADIO_PENAL = 9.15;
	/**Largo del ara chica*/
	public static final double LARGO_AREA_CHICA = LARGO_ARCO + 5.5 * 2;
	/**Ancho del area chica*/
	public static final double ANCHO_AREA_CHICA = 5.5;
	/**Radio del circulo central*/
	public static final double RADIO_CIRCULO_CENTRAL = 9.15;
	//##################################//
	//#### Parametros Configurables ####//
	//##################################//
	/**Escala inicial en pixeles por metro*/
	public static final double ESCALA = 10;
	/**Altura maxima en que  los jugadores pueden controlar el balon*/
	public static final double ALTURA_CONTROL_BALON = 1.8;
	/**Altura maxima en que el portero puede controlar el balon*/
	public static final double ALTURA_CONTROL_BALON_PORTERO = 2.5;
	/**Distancia maxima en que  los jugadores pueden controlar el balon*/
	public static final double DISTANCIA_CONTROL_BALON = 1;
	/**Distancia maxima en que el portero puede controlar el balon*/
	public static final double DISTANCIA_CONTROL_BALON_PORTERO = 1.5;
	/**Cantidad de iteraciones que se realizan durante un partido*/
	public static final int ITERACIONES = 3600;
	/**Cantidad de CREDITOS por equipo*/
	public static final double CREDITOS_INICIALES = 27.5;
	/**Frames por segundo*/
	public static final int FPS = 20;
	/**Delay entre frames*/
	public static final int DELAY = (int) (1000d / (double) FPS);
	/**Velocidad inicial vertical cuando el remate es con altura*/
	public static final double VELOCIDAD_INICIAL_VERTICAL = 0.5;
	//##############################################################################################
	/**Velocidad manima de remate (metros/iteracion)*/
	public static final double REMATE_VELOCIDAD_MIN = 1.2;
	/**Velocidad maxima de remate (metros/iteracion)*/
	public static final double REMATE_VELOCIDAD_MAX = 2.4;
	/**Factor de disminucion de velocidad del balon, cuando el balon va por aire*/
	public static final double FACTOR_DISMINUCION_VEL_BALON_AIRE = 0.97;
	/**Factor de disminucion de velocidad del balon, cuando el balon se arrastra*/
	public static final double FACTOR_DISMINUCION_VEL_BALON_SUELO = 0.93;
	/**Factor de disminucion de velocidad del balon, cuando el balon rebota*/
	public static final double FACTOR_DISMINUCION_ALTURA_BALON_REBOTE = 0.6;
	/**Aceleracion de gravedad que afecta a la velocidad vertical en los remates con altura*/
	public static final double G = 0.12;
	/**angulo por defecto usado al rematar por alto*/
	public static final double ANGULO_VERTICAL = 30;
	/**angulo vertical maximo*/
	public static final double ANGULO_VERTICAL_MAX = 60;
	//#######################################################
	/**Velocidad minima de un jugador (metros/iteracion)*/
	public static final double VELOCIDAD_MIN = 0.3;
	/**Velocidad maxima de un jugador (metros/iteracion)*/
	public static final double VELOCIDAD_MAX = 0.6;
	/**Porcentaje de error angular minimo de un jugador*/
	public static final double ERROR_MIN = 0.1;
	/**Porcentaje de error angular maximo de un jugador*/
	public static final double ERROR_MAX = 0.3;
	/**Parametro para configurar como la camara sigue la posicion del balon, mientra mayor sea mas suave seran
	 * los movimientos de la camara*/
	public static final double SEGUIMIENTO_CAMARA = 20;
	/**Cantidad de iteraciones que tienen que pasar para que un mismo jugador vuelva a rematar*/
	public static final int ITERACIONES_GOLPEAR_BALON = 10;
	/**Cantidad maxima de iteraciones para sacar, si se sobrepasan el equipo contrario sacara*/
	public static final int ITERACIONES_SAQUE = 100;
	/**radio del balon, para calcular los rebotes en el poste*/
	public static final double RADIO_BALON = .3;
	/**Distancia minima que puede estar un jugador rival mientras se realiza un saque*/
	public static final double DISTANCIA_SAQUE = 15;
	//##################################//
	//###########   Posiciones   #######//
	//##################################//
	/**esquina superior izquierda del circulo central*/
	static final Posicion esqSupIzqCircCentral = new Posicion(-Constantes.RADIO_CIRCULO_CENTRAL, -Constantes.RADIO_CIRCULO_CENTRAL);
	/**Esquina superior izquierda del campo (zona de pasto)*/
	static final Posicion esqSupIzqCampo = new Posicion(-Constantes.ANCHO_CAMPO / 2.0, -Constantes.LARGO_CAMPO / 2.0);
	/**Dimensiones del campo (zona de pasto)*/
	static final Posicion dimCampo = new Posicion(Constantes.ANCHO_CAMPO, Constantes.LARGO_CAMPO);
	/**Esquina superior izquierda del campo de juego*/
	static final Posicion esqSupIzqCampoJuego = new Posicion(-Constantes.ANCHO_CAMPO_JUEGO / 2.0, -Constantes.LARGO_CAMPO_JUEGO / 2.0);
	/**Dimensiones del campo de juego*/
	static final Posicion dimCampoJuego = new Posicion(Constantes.ANCHO_CAMPO_JUEGO, Constantes.LARGO_CAMPO_JUEGO);
	/**Esquina superior izquierda del area grande superior*/
	static final Posicion esqSupIzqAreaGrandeSup = new Posicion(-Constantes.LARGO_AREA_GRANDE / 2, -Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Esquina superior izquierda del area grande inferior*/
	static final Posicion esqSupIzqAreaGrandeInf = new Posicion(-Constantes.LARGO_AREA_GRANDE / 2, Constantes.LARGO_CAMPO_JUEGO / 2 - Constantes.ANCHO_AREA_GRANDE);
	/**dimensiones del area grande*/
	static final Posicion dimAreaGrande = new Posicion(Constantes.LARGO_AREA_GRANDE, Constantes.ANCHO_AREA_GRANDE);
	/**Esquina superior izquierda del area chica superior*/
	static final Posicion esqSupIzqAreaChicaSup = new Posicion(-Constantes.LARGO_AREA_CHICA / 2, -Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Esquina superior izquierda del area chica inferior*/
	static final Posicion esqSupIzqAreaChicaInf = new Posicion(-Constantes.LARGO_AREA_CHICA / 2, Constantes.LARGO_CAMPO_JUEGO / 2 - Constantes.ANCHO_AREA_CHICA);
	/**Dimensiones del area chica*/
	static final Posicion dimAreaChica = new Posicion(Constantes.LARGO_AREA_CHICA, Constantes.ANCHO_AREA_CHICA);
	/**Posicion del punto penal superior*/
	public static final Posicion penalInf = new Posicion(0, -Constantes.LARGO_CAMPO_JUEGO / 2 + Constantes.DISTANCIA_PENAL);
	/**Posicion del punto penal Inferior*/
	public static final Posicion penalSup = penalInf.getPosicionInvertida();
	/**Esquina superior izquierda del circulo penal superior*/
	static final Posicion esqSupIzqPenalSup = new Posicion(-Constantes.RADIO_PENAL, -Constantes.LARGO_CAMPO_JUEGO / 2 + Constantes.DISTANCIA_PENAL - Constantes.RADIO_PENAL);
	/**Esquina superior izquierda del circulo penal inferior*/
	static final Posicion esqSupDerPenalInf = new Posicion(-Constantes.RADIO_PENAL, Constantes.LARGO_CAMPO_JUEGO / 2 - Constantes.DISTANCIA_PENAL - Constantes.RADIO_PENAL);
	/**Poste izquierdo del arco superior*/
	public static final Posicion posteIzqArcoInf = new Posicion(-Constantes.LARGO_ARCO / 2, -Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Poste izquierdo del arco inferior*/
	public static final Posicion posteIzqArcoSup = new Posicion(-Constantes.LARGO_ARCO / 2, Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Poste derecho del arco superior*/
	public static final Posicion posteDerArcoInf = new Posicion(Constantes.LARGO_ARCO / 2, -Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Poste derecho del arco inferior*/
	public static final Posicion posteDerArcoSup = new Posicion(Constantes.LARGO_ARCO / 2, Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Posicion que indica el centro de la cancha*/
	public static final Posicion centroCampoJuego = new Posicion(0, 0);
	/**Posicion que indica el centro del arco superior*/
	public static final Posicion centroArcoInf = new Posicion(0, -Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Posicion que indica el centro del arco inferior*/
	public static final Posicion centroArcoSup = new Posicion(0, Constantes.LARGO_CAMPO_JUEGO / 2);
	/**Corner superior izquierdo*/
	public static final Posicion cornerInfIzq = new Posicion(esqSupIzqCampoJuego);
	/**Corner superior derecho*/
	public static final Posicion cornerInfDer = esqSupIzqCampoJuego.moverPosicion(Constantes.ANCHO_CAMPO_JUEGO, 0);
	/**Corner inferior izquierdo*/
	public static final Posicion cornerSupIzq = esqSupIzqCampoJuego.moverPosicion(0, Constantes.LARGO_CAMPO_JUEGO);
	/**Corner inferior derecho*/
	public static final Posicion cornerSupDer = cornerSupIzq.moverPosicion(Constantes.ANCHO_CAMPO_JUEGO, 0);
	//
	/**Diferencia entre maxima y mininima velocidad de remate*/
	public static double DELTA_REMATE_VELOCIDAD = REMATE_VELOCIDAD_MAX - REMATE_VELOCIDAD_MIN;
	/**Diferencia entre maxima y mininima velocidad de jugadores*/
	private static final double DELTA_VELOCIDAD = VELOCIDAD_MAX - VELOCIDAD_MIN;
	/**Diferencia entre maximo y mininimo error angular*/
	private static final double DELTA_ERROR = ERROR_MAX - ERROR_MIN;

	/**Retorna la velocidad de remate (en [metros/iteracion]) dado un factor[0..1];*/
	public static double getVelocidadRemate(double factor) {
		return REMATE_VELOCIDAD_MIN + (DELTA_REMATE_VELOCIDAD) * factor;
	}

	/**Retorna la velocidad de un jugador (en [metros/iteracion]) dado un factor[0..1];*/
	public static double getVelocidad(double factor) {
		return VELOCIDAD_MIN + (DELTA_VELOCIDAD) * factor;
	}

	/**Retorna el error angular (en [radianes]) dado un factor[0..1];*/
	public static double getErrorAngular(double factor) {
		return ERROR_MAX - (DELTA_ERROR) * factor;
	}
}
